package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.dto.course.CataSimpleInfoDTO;
import com.tianji.api.dto.course.CourseFullInfoDTO;
import com.tianji.api.dto.course.CourseSimpleInfoDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.domain.query.PageQuery;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.LearningPlanDTO;
import com.tianji.learning.domain.po.LearningLesson;
import com.tianji.learning.domain.vo.LearningLessonVO;
import com.tianji.learning.enums.LessonStatus;
import com.tianji.learning.enums.PlanStatus;
import com.tianji.learning.mapper.LearningLessonMapper;
import com.tianji.learning.service.ILearningLessonService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.tianji.learning.enums.LessonStatus.*;
import static com.tianji.learning.enums.PlanStatus.NO_PLAN;
import static com.tianji.learning.enums.PlanStatus.PLAN_RUNNING;

/**
 * <p>
 * 学生课程表 服务实现类
 * </p>
 *
 * @author yuqing
 * @since 2025-03-22
 */
@Service
@RequiredArgsConstructor
public class LearningLessonServiceImpl extends ServiceImpl<LearningLessonMapper, LearningLesson> implements ILearningLessonService {
    private final CourseClient courseClient;
    private final CatalogueClient catalogueClient;


    @Override
    public void addLessons(Long userId, List<Long> courseIds) {
        //1.根据courseIds远程调用课程信息，获取有效期信息
        List<CourseSimpleInfoDTO> CourseInfoList = courseClient.getSimpleInfoList(courseIds);
        if (CollUtils.isEmpty(CourseInfoList)) {
            log.error("课程信息查询失败");
            return;
        }
        List<LearningLesson> list = new ArrayList<>(courseIds.size());
        //2.组装数据
        for (CourseSimpleInfoDTO cInfo : CourseInfoList) {
            LearningLesson learningLesson = new LearningLesson();
            Integer validDuration = cInfo.getValidDuration();
            if (validDuration != null && validDuration > 0) {
                learningLesson.setExpireTime(LocalDateTime.now().plusMonths(validDuration));
                learningLesson.setUserId(userId);
                learningLesson.setCourseId(cInfo.getId());
                list.add(learningLesson);
            }
        }
        //3.批量保存
        saveBatch(list);
    }

    @Override
    public PageDTO<LearningLessonVO> queryMyLessonPage(PageQuery pageQuery) {
        //1.分页查询我的课表基本数据
        Long user = UserContext.getUser();
        Page<LearningLesson> page = lambdaQuery()
                .eq(LearningLesson::getUserId, user)
                .page(pageQuery.toMpPage("latest_learn_time", false));
        //1.1健壮性判断
        List<LearningLesson> records = page.getRecords();
        if (CollUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        //2.查询课程信息
        //2.1 获取课程id
        Map<Long, CourseSimpleInfoDTO> cMap = getLongCourseSimpleInfoDTOMap(records);
        //3.将课表po数据转换成VO
        List<LearningLessonVO> list = new ArrayList<>();
        for (LearningLesson record : records) {
            //3.1 拷贝基本数据
            LearningLessonVO learningLessonVO = BeanUtil.toBean(record, LearningLessonVO.class);
            //3.2根据课程Id获取课程对象，填充课程信息
            CourseSimpleInfoDTO courseSimpleInfoDTO = cMap.get(record.getCourseId());
            learningLessonVO.setCourseName(courseSimpleInfoDTO.getName());
            learningLessonVO.setCourseCoverUrl(courseSimpleInfoDTO.getCoverUrl());
            learningLessonVO.setSections(courseSimpleInfoDTO.getSectionNum());
            list.add(learningLessonVO);
        }
        return PageDTO.of(page, list);
    }

    private Map<Long, CourseSimpleInfoDTO> getLongCourseSimpleInfoDTOMap(List<LearningLesson> records) {
        List<Long> collectList = records.stream().map(LearningLesson::getCourseId).collect(Collectors.toList());
        //2.2 根据课程ids远程调用课程信息
        List<CourseSimpleInfoDTO> cInfoList = courseClient.getSimpleInfoList(collectList);
        if (CollUtils.isEmpty(cInfoList)) {
            throw new BadRequestException("课程信息查询失败");
        }
        //2.3将数据转换成Map，方便使用
        Map<Long, CourseSimpleInfoDTO> cMap = cInfoList.stream().collect(Collectors.toMap(CourseSimpleInfoDTO::getId, cInfo -> cInfo));
        return cMap;
    }


    @Override
    public Long isLessonValid(Long courseId) {
        Long user = UserContext.getUser();
        if (ObjectUtils.isEmpty(user)) {
            throw new BadRequestException("用户信息不存在");
        }
        LambdaQueryWrapper<LearningLesson> queryWrapper = new LambdaQueryWrapper<LearningLesson>()
                .eq(LearningLesson::getUserId, user)
                .eq(LearningLesson::getCourseId, courseId);
        LearningLesson learningLesson = getOne(queryWrapper);
        if (ObjectUtils.isEmpty(learningLesson)) {
            return null;
        }
        return learningLesson.getId();
    }

    @Override
    public Integer countLearningLessonByCourse(Long courseId) {
        Integer count = lambdaQuery()
                .eq(LearningLesson::getCourseId, courseId)
                .in(LearningLesson::getStatus,
                        NOT_BEGIN.getValue(),
                        LEARNING.getValue(),
                        FINISHED.getValue())
                .count();
        return count;
    }

    @Override
    public void deleteCourseFromLesson(String userId, List<Long> courseIds) {
        Long user = UserContext.getUser();
        if (ObjectUtils.isEmpty(user)) {
            throw new BadRequestException("用户信息不存在");
        }
        remove(new LambdaQueryWrapper<LearningLesson>()
                .eq(LearningLesson::getUserId, user)
                .in(LearningLesson::getCourseId, courseIds)
        );
    }

    @Override
    public LearningLessonVO getLessonById(Long courseId) {
        Long user = UserContext.getUser();
        LearningLesson lesson = lambdaQuery()
                .eq(LearningLesson::getUserId, user)
                .eq(LearningLesson::getCourseId, courseId)
                .one();
        if (ObjectUtils.isEmpty(lesson)) {
            throw new BadRequestException("课程信息不存在");
        }
        return BeanUtils.toBean(lesson, LearningLessonVO.class);
    }

    /*
     * 新增创建学习计划
     * */
    @Override
    public void addPlans(LearningPlanDTO learningPlanDTO) {
        // 1.获取用户ID
        Long userId = UserContext.getUser();
        //2.根据用户Id和课程ID查询是否有学习计划
        LearningLesson lesson = lambdaQuery()
                .eq(LearningLesson::getUserId, userId)
                .eq(LearningLesson::getCourseId, learningPlanDTO.getCourseId())
                .one();
        if (lesson == null) {
            throw new BadRequestException("学习计划不存在");
        }
        //3.根据学习计划情况进行新增或者修改
        LearningLesson learningLesson = new LearningLesson();
        learningLesson.setId(lesson.getId());
        learningLesson.setWeekFreq(learningPlanDTO.getFreq());
        if (lesson.getPlanStatus() == NO_PLAN) {
            learningLesson.setPlanStatus(PLAN_RUNNING);
        }
        updateById(learningLesson);

    }

    @Override
    public LearningLessonVO now() {
        //1.获取用户ID
        Long userId = UserContext.getUser();
        //2.查询最近学习课表基本信息
        LearningLesson lesson = lambdaQuery()
                .eq(LearningLesson::getUserId, userId)
                .orderByDesc(LearningLesson::getLatestLearnTime)
                .last("limit 1")
                .one();
        if (lesson == null) {
            return null;
        }
        //3.远程调用查询课程缺失信息（名称、图片......）
        CourseFullInfoDTO courseInfoById = courseClient.getCourseInfoById(lesson.getCourseId(), false, false);
        if (courseInfoById == null) {
            throw new BadRequestException("课程不存在");
        }
        //4.查询课表中的课程总数
        Integer count = this.lambdaQuery().eq(LearningLesson::getUserId, userId).count();
        //5.根据最近学习的课程ID获取最近学习的小节信息（名称、编号）
        Long latestSectionId = lesson.getLatestSectionId();
        List<CataSimpleInfoDTO> cataInfos = catalogueClient.batchQueryCatalogue(Arrays.asList(latestSectionId));
        if (CollUtils.isEmpty(cataInfos)) {
            throw new BadRequestException("小节信息查询失败");
        }
        CataSimpleInfoDTO cataSimpleInfoDTO = cataInfos.get(0);
        //6.组装vo数据返回
        LearningLessonVO lessonVO = BeanUtil.toBean(lesson, LearningLessonVO.class);
        lessonVO.setCourseName(courseInfoById.getName());
        lessonVO.setCourseCoverUrl(courseInfoById.getCoverUrl());
        lessonVO.setSections(courseInfoById.getSectionNum());
        lessonVO.setCourseAmount(count);
        lessonVO.setLatestSectionIndex(cataSimpleInfoDTO.getCIndex());
        lessonVO.setLatestSectionName(cataSimpleInfoDTO.getName());
        return lessonVO;
    }
}
